package com.espirit.eap.util;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import org.apache.log4j.Logger;

/**
 * Convert the Chinese to English letter
 */
public class ChineseSpeller {

	private final static Logger logger = Logger.getLogger(ChineseSpeller.class);
	
	/**
	 * 汉字转换位汉语拼音首字母，英文字符不变
	 * 
	 * @param chinese
	 *            汉字
	 * @return 拼音
	 */
	public static String convertFirstLetter(String chinese) {
		StringBuilder pinyinName = new StringBuilder();
		char[] nameChar = chinese.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < nameChar.length; i++) {
			if (nameChar[i] > 128) {
				try {
					pinyinName.append(PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0].charAt(0));
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					logger.warn("Wrong format", e);
				}
			} else {
				pinyinName.append(nameChar[i]);
			}
		}
		return pinyinName.toString();
	}

	/**
	 * 汉字转换位汉语拼音，英文字符不变
	 * 
	 * @param chinese 汉字
	 * @param onlyKeepDigitLetter don't append special char, such as ',<> etc
	 * @param appendFirstLetter append the first letter of each word, it's used by the search function
	 * @return 拼音
	 */
	public static String convert(String chinese, boolean onlyKeepDigitLetter, boolean appendFirstLetter) {
		if (chinese == null) {
			return null;
		}
		
		StringBuilder pinyinName = new StringBuilder();
		char[] nameChar = chinese.toCharArray();
		char[] firstLetters = new char[nameChar.length];
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < nameChar.length; i++) {
			if (nameChar[i] > 128) {
				try {
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat);
					if (temp != null && temp.length > 0) {
						pinyinName.append(temp[0]);
						if (appendFirstLetter) {
							firstLetters[i] = temp[0].charAt(0);
						}
					}
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					logger.warn("Wrong format", e);
				}
			} else {
				pinyinName.append(nameChar[i]);
				if (appendFirstLetter) {
					firstLetters[i] = nameChar[i];
				}
			}
		}

		if (pinyinName.length() > 0 && Character.isUpperCase(pinyinName.charAt(0))) {
			pinyinName.setCharAt(0, Character.toLowerCase(pinyinName.charAt(0)));
		}
		if (appendFirstLetter) {
			pinyinName.append(' ').append(firstLetters);
		}
		return onlyKeepDigitLetter ? formatPropertyName(pinyinName.toString()) : pinyinName.toString();
	}

	private static String formatPropertyName(String spell) {
		int len = spell.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c = spell.charAt(i);
			if (i == 0) {
				if (Character.isLetter(c)) {
					sb.append(c);
				}
			} else {
				if (Character.isLetterOrDigit(c)) {
					sb.append(c);
				}
			}
		}
		return sb.toString();
	}

}